package ref

import (
	"encoding/json"
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

func UpdateStructJsonValue(object any, parameter string, value any) error {
	// 获取结构体的反射值
	connValue := reflect.ValueOf(object)
	// 如果是指针类型，则解引用
	if connValue.Kind() == reflect.Ptr {
		connValue = connValue.Elem()
	}
	// 遍历结构体的字段
	for i := 0; i < connValue.NumField(); i++ {
		field := connValue.Type().Field(i)
		jsonTag := field.Tag.Get("json")
		// 排除带有 "-" 的 JSON 标签
		if jsonTag == "-" {
			continue
		}
		// 检查当前字段的 JSON 标签是否匹配传入的参数
		if jsonTag == parameter {
			// 获取字段的反射值
			destField := connValue.Field(i)
			// 检查字段是否可以被设置
			if destField.CanSet() {
				// 将值转为字段的类型并设置
				val := reflect.ValueOf(value)
				if val.Type().AssignableTo(destField.Type()) {
					destField.Set(val)
					return nil
				}
				// 类型不匹配，尝试将值进行 JSON 序列化和反序列化
				destJSON, err := json.Marshal(value)
				if err != nil {
					return err
				}
				err = json.Unmarshal(destJSON, destField.Addr().Interface())
				if err != nil {
					return err
				}
				return nil
			}
			return errors.New("field cannot be set")
		}
	}
	return errors.New("no matching field found")
}
func UpdateStructJsonValue1(src any, parameter string, dest any) error {
	// 获取目标和源结构体的反射值
	destValue := reflect.ValueOf(dest)
	srcValue := reflect.ValueOf(src)

	// 如果是指针类型，则解引用
	if destValue.Kind() == reflect.Ptr {
		destValue = destValue.Elem()
	}
	if srcValue.Kind() == reflect.Ptr {
		srcValue = srcValue.Elem()
	}

	// 确保源和目标都是结构体
	if destValue.Kind() != reflect.Struct || srcValue.Kind() != reflect.Struct {
		return errors.New("both parameters must be structs")
	}

	// 遍历目标结构体的字段
	for i := 0; i < destValue.NumField(); i++ {
		field := destValue.Type().Field(i)
		jsonTag := field.Tag.Get("json")

		// 排除带有 "-" 的 JSON 标签
		if jsonTag == "-" {
			continue
		}

		// 检查当前字段的 JSON 标签是否匹配传入的参数
		if jsonTag == parameter {
			// 获取目标字段的反射值
			destField := destValue.Field(i)

			// 检查目标字段是否可以被设置
			if destField.CanSet() {
				// 获取源字段的值
				srcField := srcValue.FieldByName(field.Name)

				// 确保源字段有效并且类型可赋值到目标字段
				if srcField.IsValid() && srcField.Type().AssignableTo(destField.Type()) {
					destField.Set(srcField)
					return nil
				}
				return errors.New("source value type is not assignable to destination field")
			}
			return errors.New("field cannot be set")
		}
	}

	return errors.New("no matching field found")
}

// MapStructValues 映射结构体值的递归函数
func MapStructValues(sourceValue reflect.Value, destinationValue reflect.Value) {
	// 检查源值和目标值的类型是否相同
	//if sourceValue.Type() != destinationValue.Type() {
	//	return
	//}
	fmt.Println("----111:", reflect.TypeOf(sourceValue), destinationValue)
	// 解引用指针类型的值
	if sourceValue.Kind() == reflect.Ptr {
		sourceValue = sourceValue.Elem()
	}
	if destinationValue.Kind() == reflect.Ptr {
		destinationValue = destinationValue.Elem()
	}
	sinceStructSeq := 0
	// 处理结构体字段
	for i := 0; i < sourceValue.NumField(); i++ {
		sourceField := sourceValue.Type().Field(i)
		sourceFieldValue := sourceValue.Field(i)
		// 检查字段是否带有json标签
		if jsonTag := sourceField.Tag.Get("json"); jsonTag != "" {
			sinceStructSeq++
			destinationField := destinationValue.FieldByName(sourceField.Name)
			// 检查目标结构体是否存在字段
			if destinationField.IsValid() && destinationField.CanSet() {
				// 检查字段类型
				if destinationField.Type() == sourceFieldValue.Type() {
					// 设置字段值
					destinationField.Set(sourceFieldValue)
				} else {
					// 如果字段类型不匹配，尝试使用JSON进行转换
					destinationJSON, _ := json.Marshal(sourceFieldValue.Interface())
					_ = json.Unmarshal(destinationJSON, destinationField.Addr().Interface())
				}
			}
			// 如果是结构体类型，则递归处理子结构体
			if sourceFieldValue.Kind() == reflect.Struct {
				MapStructValues(sourceFieldValue, destinationValue.Field(sinceStructSeq-1))
			}
			//// 如果是指针类型，则创建新的目标指针并递归处理
			//if sourceFieldValue.Kind() == reflect.Ptr && destinationField.Kind() == reflect.Ptr {
			//	if !sourceFieldValue.IsNil() {
			//		newDestinationValue := reflect.New(destinationField.Type().Elem())
			//		mapStructValues(sourceFieldValue.Elem(), newDestinationValue.Elem())
			//		destinationField.Set(newDestinationValue)
			//	}
			//}
		}
	}
}

func StructToMap(input interface{}) (map[string]interface{}, error) {
	result := make(map[string]interface{})
	val := reflect.ValueOf(input)
	// 确保输入是结构体类型
	if val.Kind() != reflect.Struct {
		return nil, fmt.Errorf("expected a struct but got %s", val.Kind())
	}
	typ := val.Type()
	for i := 0; i < val.NumField(); i++ {
		field := typ.Field(i)
		value := val.Field(i)
		// 获取 JSON 标签
		jsonTag := field.Tag.Get("json")
		if jsonTag == "" {
			continue // 跳过没有 JSON 标签的字段
		}
		switch value.Kind() {
		case reflect.Struct:
			nestedMap, _ := StructToMap(value.Interface())
			result[jsonTag] = nestedMap
		case reflect.Slice: // 处理切片类型的字段
			slice := make([]interface{}, value.Len())
			for j := 0; j < value.Len(); j++ {
				item, _ := StructToMap(value.Index(j).Interface())
				slice[j] = item
			}
			result[jsonTag] = slice
		default:
			result[jsonTag] = value.Interface()
		}
	}
	return result, nil
}
func MapToStruct(data map[string]any, result interface{}) error {
	val := reflect.ValueOf(result)
	if val.Kind() != reflect.Ptr || val.IsNil() {
		return fmt.Errorf("result must be a non-nil pointer to a struct")
	}
	val = val.Elem() // 获取指针所指向的值
	typ := val.Type()

	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		jsonTag := field.Tag.Get("json")
		if jsonTag == "" {
			continue
		}
		if value, ok := data[jsonTag]; ok {
			fieldVal := val.Field(i)
			if fieldVal.CanSet() {
				switch fieldVal.Kind() {
				case reflect.String:
					if strVal, ok := value.(string); ok {
						fieldVal.SetString(strVal)
					}
				case reflect.Int, reflect.Int64:
					if value == nil {
						fieldVal.SetInt(0) // 默认值
						// Handle nil values for int fields
						continue
					}
					switch value := value.(type) {
					case float64:
						fieldVal.SetInt(int64(value))
					case int:
						fieldVal.SetInt(int64(value))
					case int64:
						fieldVal.SetInt(value)
					case uint64:
						fieldVal.SetInt(int64(value))
					case string:
						if strings.EqualFold(value, "NULL") || strings.EqualFold(value, "0") {
							fieldVal.SetInt(0)
						} else {
							if valInt, err := strconv.Atoi(value); err == nil {
								fieldVal.SetInt(int64(valInt))
							}
						}
					default:
						fmt.Printf("字段 %s 的值不是 float64 或 int: 值类型为:%v 值为:%v \n", jsonTag, reflect.TypeOf(value), value)
					}
				case reflect.Bool:
					if boolVal, ok := value.(bool); ok {
						fieldVal.SetBool(boolVal)
					} else {
						fmt.Printf("Field %s value is not a bool: %v\n", jsonTag, value)
					}
				case reflect.Struct:
					// 递归调用处理嵌套结构体
					nestedData, ok := value.(map[string]any)
					if ok {
						nestedStruct := reflect.New(field.Type).Interface()
						if err := MapToStruct(nestedData, nestedStruct); err != nil {
							return err
						}
						fieldVal.Set(reflect.ValueOf(nestedStruct).Elem())
					}
				case reflect.Slice:
					var dataSlice []any
					switch value.(type) {
					case []any:
						dataSlice = value.([]any)
					case []string:
						dataSlice = func() (res []any) {
							for _, v := range value.([]string) {
								res = append(res, v)
							}
							return
						}()
					default:
						fmt.Printf("Value for field %s is not a slice: %v\n", jsonTag, value)
					}
					slice := reflect.MakeSlice(fieldVal.Type(), len(dataSlice), len(dataSlice))
					for j, item := range dataSlice {
						nestedStruct := reflect.New(field.Type.Elem()).Interface()
						if nestedData, ok := item.(map[string]any); ok {
							if err := MapToStruct(nestedData, nestedStruct); err != nil {
								return err
							}
							slice.Index(j).Set(reflect.ValueOf(nestedStruct).Elem())
						} else if strItem, ok := item.(string); ok {
							// 处理字符串切片
							slice.Index(j).SetString(strItem)
						} else {
							fmt.Printf("Item at index %d is not a map[string]any or string: %v\n", j, item)
						}
					}
					fieldVal.Set(slice)
				case reflect.Interface:
					if value == nil {
						continue
					}
					fieldVal.Set(reflect.ValueOf(value))
				default:
					fmt.Printf("Unsupported field type: %s\n", fieldVal.Kind())
				}
			}
		}
	}
	return nil
}
/*
StructSubJsonNameToMap ==> map

			  input ==>
			type Address struct {
				Street  string `json:"street"`
				City    string `json:"city"`
				Country string `json:"country"`
			}
			type Person struct {
				Name    string  `json:"name"`
				Age     int     `json:"age"`
				Gender  string  `json:"gender"`
				Address Address `json:"address"`
		}

		  person := Person{
				Name:   "Alice",
				Age:    30,
				Gender: "Female",
				Address: Address{
					Street:  "123 Main St",
					City:    "New York",
					Country: "USA",
				},
			}
			output ==>
			map[forceIndex: partition.ipg:[] partition.pg:[] sec.column:[] sec.lock: sec.unlock: whereAdd: whereSql:]
	}
*/
func StructSubJsonNameToMap(obj interface{}) (map[string]interface{}, error) {
	objType := reflect.TypeOf(obj)
	objValue := reflect.ValueOf(obj)
	if objType.Kind() == reflect.Ptr {
		objType = objType.Elem()
		objValue = objValue.Elem()
	}
	if objType.Kind() != reflect.Struct {
		return nil, fmt.Errorf("obj must be a struct or a pointer to struct")
	}
	result := make(map[string]interface{})
	for i := 0; i < objType.NumField(); i++ {
		field := objType.Field(i)
		value := objValue.Field(i)
		tag := field.Tag.Get("json")
		if tag == "" || tag == "-" {
			continue
		}
		if field.Type.Kind() == reflect.Struct {
			nestedResult, err := StructSubJsonNameToMap(value.Interface())
			if err != nil {
				return nil, err
			}
			for nestedKey, nestedValue := range nestedResult {
				result[tag+"."+nestedKey] = nestedValue
			}
		} else {
			result[tag] = value.Interface()
		}
	}
	return result, nil
}
/*
StructToMapAny   struct json ==>map[string]any

	===>input
	type Person struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	}
	p := Person{
		Name: "John Doe",
		Age:  30,
	}
	output <=====
	map[age:30 name:John Doe]
*/
func StructToMapAny(v any) (map[string]any, error) {
	// 获取 v 的反射值
	value := reflect.ValueOf(v)
	// 检查 v 是否为指针
	if value.Kind() == reflect.Ptr {
		value = value.Elem()
	}
	// 检查 v 是否为结构体
	if value.Kind() != reflect.Struct {
		return nil, fmt.Errorf("input must be a struct")
	}
	// 初始化一个空的 map
	m := make(map[string]interface{})
	// 遍历结构体的字段
	for i := 0; i < value.NumField(); i++ {
		field := value.Field(i)
		fieldName := value.Type().Field(i).Name
		tag := value.Type().Field(i).Tag.Get("json")
		if tag != "" {
			fieldName = tag
		}
		m[fieldName] = field.Interface()
	}
	return m, nil
}
// StructNameJsonToSlice struct name json ===> slice
/*
	input ==>
	person := Person{
		Name:  "Alice" json:"name",
		Age:   25  json:"age",
		Email: "alice@example.com" json:"email",
	}
    output <==
	[]any{"name","age","email"}
*/
func StructNameJsonToSlice(s any) []any {
	var rowC []any
	objValue := reflect.ValueOf(s)
	if objValue.Kind() != reflect.Struct {
		//return nil, fmt.Errorf("传入的参数必须是结构体类型")
	}
	objType := objValue.Type()
	data := make(map[string]any)
	for i := 0; i < objValue.NumField(); i++ {
		field := objValue.Field(i)
		fieldType := objType.Field(i)
		fieldName := fieldType.Name

		jsonTag := fieldType.Tag.Get("json")
		if jsonTag != "" {
			fieldName = jsonTag
			rowC = append(rowC, fieldName)
			data[fieldName] = field.Interface()
		}

	}
	return rowC
}

